package com.ruoyi.onlyoffice.controller;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.onlyoffice.domain.OnFile;
import com.ruoyi.onlyoffice.service.FileService;
import com.ruoyi.onlyoffice.service.IOnFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.*;

/**
 * oo存档文件Controller
 * 
 * @author lgq
 * @date 2023-08-25
 */
@RestController
@RequestMapping("/oo/oofile")
public class OnFileController extends BaseController
{
    @Autowired
    private IOnFileService onFileService;

    @Autowired
    private FileService fileService;


    /**
     * 查询oo存档文件列表
     */
    @GetMapping("/list")
    public TableDataInfo list(OnFile onFile)
    {
        startPage();
        List<OnFile> list = onFileService.selectOnFileList(onFile);
        return getDataTable(list);
    }

    /**
     * 查询oo存档文件列表
     */
    @GetMapping("/listByReportId")
    public TableDataInfo list(String reportId)
    {
        startPage();
        List<OnFile> list = onFileService.selectOnFileByReportId(reportId);
        return getDataTable(list);
    }

    /**
     * 导出oo存档文件列表
     */
    @Log(title = "oo存档文件", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(OnFile onFile)
    {
        List<OnFile> list = onFileService.selectOnFileList(onFile);
        ExcelUtil<OnFile> util = new ExcelUtil<OnFile>(OnFile.class);
        return util.exportExcel(list, "file");
    }

    /**
     * 获取oo存档文件详细信息
     */
    @GetMapping(value = "/{fileId}")
    public AjaxResult getInfo(@PathVariable("fileId") String fileId)
    {
        return AjaxResult.success(onFileService.selectOnFileById(fileId));
    }

    /**
     * 新增oo存档文件
     */
    @Log(title = "oo存档文件", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody OnFile onFile)
    {
        return toAjax(onFileService.insertOnFile(onFile));
    }

    /**
     * 修改oo存档文件
     */
    @Log(title = "oo存档文件", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody OnFile onFile)
    {
        return toAjax(onFileService.updateOnFile(onFile));
    }

    /**
     * 删除oo存档文件
     */
    @Log(title = "oo存档文件", businessType = BusinessType.DELETE)
	@DeleteMapping("/{fileIds}")
    public AjaxResult remove(@PathVariable String[] fileIds)
    {
        return toAjax(onFileService.deleteOnFileByIds(fileIds));
    }

    /**
     * oo文件上传接口
     */
    @PostMapping("/upload")
    @ResponseBody
    public AjaxResult ooupload(@RequestParam("file") MultipartFile[] file) {
        int i = 0;
        for(MultipartFile multipartFile:file){
            CommonsMultipartFile commonsMultipartFile = (CommonsMultipartFile) multipartFile;
            String filename = multipartFile.getOriginalFilename();
            // 获取文件后缀
            String suffix = filename.substring(filename.lastIndexOf(".") + 1);
            String fileId = "";
            try {
                fileId = onFileService.saveFile(commonsMultipartFile.getBytes(), suffix);
            } catch (Exception e) {
                e.printStackTrace();
            }
            OnFile onFile = new OnFile();
            onFile.setFileId(fileId);
            onFile.setFileName(filename);
            onFile.setVersion("1.0.0");
            onFile.setFileSize(commonsMultipartFile.getSize());
            onFile.setFileType(suffix);
            onFileService.insertOnFile(onFile);
            i++;
        }
        if (file.length == i){
            return AjaxResult.success("文件上传成功");
        }
        return AjaxResult.success("文件上传失败");
    }

    /**
     * 文档编辑返回oo配置信息
     */
    @PostMapping("/config")
    public AjaxResult openDucumentConfig(@RequestBody OnFile onFile) {
        OnFile onFilei = onFileService.selectOnFileById(onFile.getFileId());
        //配置信息
        if(null != onFilei) {
            Map<String,Object> map = new HashMap<>();
            map.put("fileId",onFilei.getFileId());
            map.put("fileName",onFilei.getFileName());
            map.put("fileType",onFilei.getFileType());
            map.put("fileSize",onFilei.getFileSize());
            map.put("version",onFilei.getVersion());
            Map config = onFileService.openDocument(map, onFile.getMode(), true, onFile.getUserId());
            String res = JSONObject.toJSONString(config);
            return AjaxResult.success(res);
        }
        return AjaxResult.error();
    }

    /**
     * 文档编辑服务使用JavaScript API通知callbackUrl，向文档存储服务通知文档编辑的状态。
     * 文档编辑服务使用具有正文中的信息的POST请求。
     * https://api.onlyoffice.com/editors/callback
     * <p>
     * 当我们关闭编辑窗口后，十秒钟左右only office会将它存储的我们的编辑后的文件
     * 0 - 找不到具有密钥标识符的文档
     * 1 - 正在编辑文档
     * 2 - 文档已准备好保存
     * 3 - 发生文档保存错误
     * 4 - 不作任何更改就关闭文档
     * 6 - 正在编辑文档，但保存当前文档状态
     * 7 - 强制保存文档时发生错误
     *
     */
    @RequestMapping("/save")
    public void saveFile(HttpServletRequest request, HttpServletResponse response) {
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            // 获取传输的json数据
            Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
            String body = scanner.hasNext() ? scanner.next() : "";
            JSONObject jsonObject = JSONObject.parseObject(body);
            fileService.documentSave(jsonObject);
        } catch (Exception e) {
            e.printStackTrace();
            writer.write("{\"error\":-1}");
            return;
        }
        /*
         * status = 1，我们给onlyOffice的服务返回{"error":"0"}的信息。
         * 这样onlyOffice会认为回调接口是没问题的，这样就可以在线编辑文档了，否则的话会弹出窗口说明
         */
        if (Objects.nonNull(writer)) {
            writer.write("{\"error\":0}");
        }
    }

    /**
     * 保存文件
     * @param id
     * @return
     */
    @GetMapping("/savefile/{id}")
    public AjaxResult save(@PathVariable("id") String id){
        OnFile onFile = onFileService.selectOnFileById(id);
        String key = onFileService.getKey(onFile.getFileId());
        String msg = onFileService.save(key,String.valueOf(SecurityUtils.getLoginUser().getUser().getUserId()));
        //保存成功
        if(StringUtils.equalsIgnoreCase(msg, "保存成功")) {
            //获取最新的fileId
            onFile = onFileService.selectNewVersion(onFile.getReportId());
            return AjaxResult.success(msg, onFile.getFileId());
        }
        return AjaxResult.success(msg);
    }


    /**
     *下载文件
     * @param id
     * @param isBrowser 用来判断是否是oo服务的回调下载  1.没有值 = oo服务回调下载。2.有值 = 页面手动下载
     * @param response
     */
    @RequestMapping("/download/{id}")
    public void download(@PathVariable("id")  String id, String isBrowser, HttpServletResponse response) {
        try {
            onFileService.download(id,isBrowser,response);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
